import 'package:flutter/material.dart';


/*

 ListView是最常用的可滚动组件之一，它可以沿一个方向线性排布所有子组件，并且它也支持基于Sliver的延迟构建模型。
 我们看看ListView的默认构造函数定义：

 ListView({
   ...  
   //可滚动widget公共参数
   Axis scrollDirection = Axis.vertical,
   bool reverse = false,
   ScrollController controller,
   bool primary,
   ScrollPhysics physics,
   EdgeInsetsGeometry padding,
 
   //ListView各个构造函数的共同参数  
   double itemExtent,
   bool shrinkWrap = false,
   bool addAutomaticKeepAlives = true,
   bool addRepaintBoundaries = true,
   double cacheExtent,
 
   //子widget列表
   List<Widget> children = const <Widget>[],
 })
 上面参数分为两组：第一组是可滚动组件的公共参数，本章第一节中已经介绍过，不再赘述；第二组是ListView各个构造函
 数（ListView有多个构造函数）的共同参数，我们重点来看看这些参数：
 
 itemExtent：该参数如果不为null，则会强制children的“长度”为itemExtent的值；这里的“长度”是指滚动方向上子组件的长度，
    也就是说如果滚动方向是垂直方向，则itemExtent代表子组件的高度；如果滚动方向为水平方向，则itemExtent就代表子组件的
    宽度。在ListView中，指定itemExtent比让子组件自己决定自身长度会更高效，这是因为指定itemExtent后，滚动系统可以提前
    知道列表的长度，而无需每次构建子组件时都去再计算一下，尤其是在滚动位置频繁变化时（滚动系统需要频繁去计算列表高度）。
 shrinkWrap：该属性表示是否根据子组件的总长度来设置ListView的长度，默认值为false 。默认情况下，ListView的会在滚动方
    向尽可能多的占用空间。当ListView在一个无边界(滚动方向上)的容器中时，shrinkWrap必须为true。
 addAutomaticKeepAlives：该属性表示是否将列表项（子组件）包裹在AutomaticKeepAlive 组件中；典型地，在一个懒加载列表
    中，如果将列表项包裹在AutomaticKeepAlive中，在该列表项滑出视口时它也不会被GC（垃圾回收），它会使用
    KeepAliveNotification来保存其状态。如果列表项自己维护其KeepAlive状态，那么此参数必须置为false。
 addRepaintBoundaries：该属性表示是否将列表项（子组件）包裹在RepaintBoundary组件中。当可滚动组件滚动时，将列表项包裹
    在RepaintBoundary中可以避免列表项重绘，但是当列表项重绘的开销非常小（如一个颜色块，或者一个较短的文本）时，不添加
    RepaintBoundary反而会更高效。和addAutomaticKeepAlive一样，如果列表项自己维护其KeepAlive状态，那么此参数必须置
    为false。
    
 注意：上面这些参数并非ListView特有，在本章后面介绍的其它可滚动组件也可能会拥有这些参数，它们的含义是相同的。

*/


class ListView1Page extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("List View 1"),
      ),
      body: Flex(
        direction: Axis.vertical,
        children: <Widget>[
          Expanded(
            flex: 1,
            child: Container(
              color: Colors.blue,
              child: Scrollbar(
                child: ListView(
                  shrinkWrap: true,
                  padding: const EdgeInsets.all(20),
                  children: "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map((c) => Text("List View - " + c, textScaleFactor: 2)).toList(),
                ),
              )
            ) 
          ),
          Expanded(
            flex: 1,
            child: Container(
              color: Colors.red,
              child: Scrollbar(
                child: ListView.builder(
                  itemCount: 100,
                  itemExtent: 50,
                  itemBuilder: (BuildContext context, int index) => ListTile(
                    title: Text("List View Builder - $index")
                  ),
                ),
              ),
            )
          ),
          Expanded(
            flex: 1,
            child: Container(
              color: Colors.yellow,
              child: Scrollbar(
                child: ListView.separated(
                  itemCount: 100,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text("List View Separated - $index")
                    );
                  },
                  separatorBuilder: (BuildContext context, int index) {
                    return index % 2 == 0 ? Divider(
                      color: Colors.blue,
                    ) : Divider(
                      color: Colors.red,
                    );
                  },
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}